#include<string>
#include<algorithm>
#include<functional>
#include<map>
#include<string_view>
#include<numeric>
#include<iostream>
#include<type_traits>
#include<iterator>

using std::ostream_iterator;
using std::find_if;
using std::accumulate;
using std::string_view;
using std::pair;
using std::string;
using std::search;
using std::make_reverse_iterator;
using std::cout;
using std::is_same;
using std::find;


struct regexSplit {};


//区间值（固定）作为split规则
template<typename SOURCEITER, typename FINDITER, typename FUNCTION>
void split(SOURCEITER sourceBegin, SOURCEITER sourceEnd, FINDITER findBegin, FINDITER findEnd, FUNCTION fun)
{
	if (sourceEnd - sourceBegin && findEnd - findBegin)
	{
		auto findStrSize{ findEnd - findBegin };
		SOURCEITER iterBegin{ sourceBegin }, iterEnd{ sourceBegin };
		while (iterBegin != sourceEnd)
		{
			iterEnd = search(iterBegin, sourceEnd, findBegin, findEnd);
			if (iterEnd - iterBegin)
				fun(iterBegin, iterEnd);
			iterBegin = iterEnd + (iterEnd != sourceEnd ? findStrSize : 0);
		}
	}
}



//第二种支持两种自定义规则split，第一种为不定规则但值只有1位的， 第二种为类似正则的自定义规则，pair中保存首尾位置，如果没有符合规则的split区间串，则使用者应设置位置为end，
//至于贪婪算法什么的，靠使用者的功力啦，自由发挥
template<typename SPLITTYPE = void,typename SOURCEITER, typename SPLITFUNCTION, typename FUNCTION>
void split_if(SOURCEITER sourceBegin, SOURCEITER sourceEnd, SPLITFUNCTION sf, FUNCTION fun)           
{
	if (sourceEnd - sourceBegin)
	{
		if constexpr (is_same<SPLITTYPE, void>::value)
		{
			SOURCEITER iterBegin{ sourceBegin }, iterEnd{ sourceBegin };
			while (iterBegin != sourceEnd)
			{
				iterEnd = find_if(iterBegin, sourceEnd, sf);
				if (iterEnd - iterBegin)
					fun(iterBegin, iterEnd);
				iterBegin = iterEnd + (iterEnd != sourceEnd ? 1 : 0);
			}
		}
		else if (is_same<SPLITTYPE, regexSplit>::value)
		{
			SOURCEITER iterBegin{ sourceBegin }, iterEnd{ sourceBegin };
			pair<SOURCEITER, SOURCEITER>splitPos;
			while (iterBegin != sourceEnd)
			{
				sf(iterBegin, sourceEnd, splitPos);
				if(splitPos.first- iterBegin)
					fun(iterBegin, splitPos.first);
				iterBegin = splitPos.second + (splitPos.second != sourceEnd ? 1 : 0);
			}
		}
	}
}




int main()
{
	string str{ "192.169.0.1:8052" };
	const char *str1{ ":" };
	pair<string_view, int> ipPort;
	bool check{ false };
	check = false;

	//区间值做split规则，使用第一种处理
	split(&str[0], &str[0] + str.size(), str1, str1 + strlen(str1), [&ipPort, &check](auto const iterBegin, auto const iterEnd)
	{
		if (!check)
		{
			ipPort.first = string_view(iterBegin, iterEnd - iterBegin);
			check = true;
		}
		else
		{
			int num{ -1 }, temp{ 1 };
			ipPort.second = accumulate(make_reverse_iterator(iterEnd), make_reverse_iterator(iterBegin), 0, [&num, &temp](auto &sum, auto const ch)
			{
				if (++num)temp *= 10;
				return sum += (ch - '0')*temp;
			});
		}
	});
	cout << ipPort.first << "  " << ipPort.second << "\n\n";

	//区间值做split规则，使用第一种处理
	str.assign("1||02||034||5||965||1000||8536");
	string str2{ "||" };
	int max{ INT_MIN };
	split(str.cbegin(), str.cend(), str2.cbegin(), str2.cend(), [&max](auto const iterBegin, auto const iterEnd)
	{
		int num{ -1 }, temp{ 1 };
		num = accumulate(make_reverse_iterator(iterEnd), make_reverse_iterator(iterBegin), 0, [&num, &temp](auto &sum, auto const ch)
		{
			if (++num)temp *= 10;
			return sum += (ch - '0')*temp;
		});
		if (num > max)
			max = num;
	});
	cout << max << "\n\n";

	//不定值做split规则，但固定只有1位的情况，使用第二种的普通模式处理
	max = 0;
	str.assign("1.02|034!5'965{1000]8536");
	split_if(str.cbegin(), str.cend(), [](auto const ch) {return !isdigit(ch); }, [&max](auto const iterBegin, auto const iterEnd)
	{
		int num{ -1 }, temp{ 1 };
		num = accumulate(make_reverse_iterator(iterEnd), make_reverse_iterator(iterBegin), 0, [&num, &temp](auto &sum, auto const ch)
		{
			if (++num)temp *= 10;
			return sum += (ch - '0')*temp;
		});
		if (num > max)
			max = num;
	});
	cout << max << "\n\n";

	//不定值做split规则，但位数不固定的情况，使用第二种的regexsplit类正则模式处理
	str.assign("</bs>text</test>document</dot>name</password>jkmnjhkd</feggrdgregergreger>");
	split_if<regexSplit>(str.cbegin(), str.cend(), [](auto const iterBegin, auto const iterEnd, pair<string::const_iterator, string::const_iterator> &p1)
	{
		if ((p1.first = find(iterBegin, iterEnd, '<')) == iterEnd)
		{
			p1.second = iterEnd;
			return;
		}
		if ((p1.second = find(p1.first + 1, iterEnd, '>')) == iterEnd)
			p1.first = iterEnd;
	},	
		[](auto const iterBegin, auto const iterEnd)
	{
		copy(iterBegin, iterEnd, ostream_iterator<char>(cout));
		cout << '\n';
	});
	cout << '\n';


	//不定值做split规则，但位数不固定的情况，使用第二种的regexsplit类正则模式处理
	str.assign("textdocumentnamejkmnjhkd");
	split_if<regexSplit>(str.cbegin(), str.cend(), [](auto const iterBegin, auto const iterEnd, pair<string::const_iterator, string::const_iterator> &p1)
	{
		if ((p1.first = find(iterBegin, iterEnd, '<')) == iterEnd)
		{
			p1.second = iterEnd;
			return;
		}
		if ((p1.second = find(p1.first + 1, iterEnd, '>')) == iterEnd)
			p1.first = iterEnd;
	},
		[](auto const iterBegin, auto const iterEnd)
	{
		copy(iterBegin, iterEnd, ostream_iterator<char>(cout));
		cout << '\n';
	});
	cout << '\n';
	return 0;
}
